local EmoTalentUtil = require "packages.emopack.pkg.emopack_talent.util" -- 加载战法核心
local skel = require "packages.emopack.pkg.emopack_talent.talents.core" ---@type SkillSkeleton

local hasTalent = EmoTalentUtil.hasTalent
local logTalent = EmoTalentUtil.logTalent
local invokeTalent = EmoTalentUtil.invokeTalent
local handleInvokedTalents = EmoTalentUtil.handleInvokedTalents
local forRandom = EmoTalentUtil.forRandom
local timesCheckFilter = EmoTalentUtil.timesCheckFilter



-- 用于加载杂项战法。例如 判定类，技能类，拼点类，翻面类

--- 判定生效后
skel:addEffect(fk.FinishJudge, {
  mute = true,
  is_delay_effect = true,
  can_trigger = function (self, event, target, player, data)
    local cost_data = {}
    if hasTalent(player, "emot_jiaoyi") and not target.dead and player:isFriend(target) and data.card then
      table.insert(cost_data, "emot_jiaoyi") -- 教义
    end
    if target == player then
      if hasTalent(player, "emot_shenzhu") then
        table.insert(cost_data, "emot_shenzhu") -- 神祝
      end
    end
    if timesCheckFilter(cost_data, player) then
      event:setCostData(self, cost_data)
      return true
    end
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    local cost_data = event:getCostData(self) or {}
    if table.contains(cost_data, "emot_jiaoyi") and not target.dead then -- 教义
      invokeTalent(player, "emot_jiaoyi", event)
      if data.card.color == Card.Red then
        room:recover { num = 1, skillName = skel.name, who = target, recoverBy = player }
      else
        room:changeMaxHp(target, 1)
      end
    end
    if table.contains(cost_data, "emot_shenzhu") and not player.dead then -- 神祝
      invokeTalent(player, "emot_shenzhu", event)
      if room:getCardArea(data.card) == Card.Processing then
        room:obtainCard(player, data.card, true, fk.ReasonPrey, player, skel.name)
      end
      if data.card and data.card.suit == Card.Spade then
        local targets = table.filter(room.alive_players, function(p) return player:isEnemy(p) end)
        if #targets > 0 then
          local to = table.random(targets)
          room:doIndicate(player, {to})
          room:delay(200)
          room:damage { from = player, to = to, damage = 1, skillName = skel.name, damageType =  fk.ThunderDamage }
        end
      end
    end
    handleInvokedTalents(player, event)
  end,
})

--- 判定牌生效前
skel:addEffect(fk.AskForRetrial, {
  mute = true,
  is_delay_effect = true,
  can_trigger = function(self, event, target, player, data)
    local cost_data = {}
    if hasTalent(player, "emot_wuya") and not player.dead then -- 乌鸦
      table.insert(cost_data, "emot_wuya")
    end
    if timesCheckFilter(cost_data, player) then
      event:setCostData(self, cost_data)
      return true
    end
  end,
  on_cost = Util.TrueFunc,
  on_use = function(self, event, target, player, data)
    local room = player.room
    local cost_data = event:getCostData(self) or {}
    if table.contains(cost_data, "emot_wuya") then -- 乌鸦
      invokeTalent(player, "emot_wuya", event)
      local orig = data.card:getEffectiveId()
      local card_data = {
        { "judgecard", {orig} },
        { "emot_wuya", room:getNCards(5, "bottom") }
      }
      local cid = room:askToChooseCard(player, {
        target = player, skill_name = "emot_wuya", prompt = "#emot_wuya-ask",
        flag = { card_data = card_data }
      })
      if cid ~= orig then
        room:changeJudge{
          player = player, card = Fk:getCardById(cid), skillName = skel.name, data = data
        }
      end
    end
    handleInvokedTalents(player, event)
  end,
})


--- 发动技能时，用于防止技能发动。为了防止嵌套，用refresh
skel:addEffect(fk.SkillEffect, {
  can_refresh = function (self, event, target, player, data)
    local skill = data.skill
    if hasTalent(player, "emot_qingwa") and not player.dead and target and player:isEnemy(target) -- 青蛙
     and skill and skill:isPlayerSkill(target) and table.contains(target:getSkillNameList(), skill:getSkeleton().name)
      and not data.prevented and skill:isInstanceOf(TriggerSkill)
      and not skill:hasTag(Skill.Permanent) then
      return true
    end
  end,
  on_refresh = function(self, event, target, player, data)
    if forRandom(player, 0.2, "emot_qingwa") then
      logTalent(player, "emot_qingwa")
      data.prevented = true
    end
  end,
})

--- 获得技能后
skel:addEffect(fk.EventAcquireSkill, {
  mute = true,
  is_delay_effect = true,
  can_trigger = function (self, event, target, player, data)
    local cost_data = {}
    if hasTalent(player, "emot_yuanbo") and not player.dead and target == player and data.skill:isPlayerSkill(player) then -- 渊博
      table.insert(cost_data, "emot_yuanbo")
    end
    if timesCheckFilter(cost_data, player) then
      event:setCostData(self, cost_data)
      return true
    end
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    local cost_data = event:getCostData(self) or {}
    if table.contains(cost_data, "emot_yuanbo") and not player.dead then -- 渊博
      invokeTalent(player, "emot_yuanbo", event)
      room:addPlayerMark(player, MarkEnum.AddMaxCards, 2)
      player:drawCards(2, skel.name)
    end
    handleInvokedTalents(player, event)
  end,
})

-- 拼点信息确认后
skel:addEffect(fk.PindianResultConfirmed, {
  mute = true,
  is_delay_effect = true,
  can_trigger = function(self, event, target, player, data)
    local cost_data = {}
    if hasTalent(player, "emot_xianhai") then -- 陷害
      if (not data.from.dead and player:isEnemy(data.from) and data.from ~= data.winner)
      or (not data.to.dead and player:isEnemy(data.to) and data.to ~= data.winner) then
        table.insert(cost_data, "emot_xianhai")
      end
    end
    if timesCheckFilter(cost_data, player) then
      event:setCostData(self, cost_data)
      return true
    end
  end,
  on_cost = Util.TrueFunc,
  on_use = function(self, event, target, player, data)
    local room = player.room
    local cost_data = event:getCostData(self) or {}
    if table.contains(cost_data, "emot_xianhai") and not player.dead then -- 陷害
      invokeTalent(player, "emot_xianhai", event)
      if not data.from.dead and player:isEnemy(data.from) and data.from ~= data.winner then
        room:loseHp(data.from, data.fromCard.number, skel.name)
      end
      if not data.to.dead and player:isEnemy(data.to) and data.to ~= data.winner then
        room:loseHp(data.to, data.toCard.number, skel.name)
      end
    end
    handleInvokedTalents(player, event)
  end,
})


-- 连环状态改变后
skel:addEffect(fk.ChainStateChanged, {
  mute = true,
  is_delay_effect = true,
  can_trigger = function(self, event, target, player, data)
    local cost_data = {}
    if hasTalent(player, "emot_zhumu") and not player.dead then -- 蛛母
      table.insert(cost_data, "emot_zhumu")
    end
    if timesCheckFilter(cost_data, player) then
      event:setCostData(self, cost_data)
      return true
    end
  end,
  on_cost = Util.TrueFunc,
  on_use = function(self, event, target, player, data)
    local room = player.room
    local cost_data = event:getCostData(self) or {}
    if table.contains(cost_data, "emot_zhumu") and not player.dead then -- 蛛母
      invokeTalent(player, "emot_zhumu", event, 2)
      player:drawCards(1, skel.name)
    end
    handleInvokedTalents(player, event)
  end,
})

-- 翻面前
skel:addEffect(fk.BeforeTurnOver, {
  mute = true,
  is_delay_effect = true,
  can_trigger = function(self, event, target, player, data)
    local cost_data = {}
    if target == player then
      if hasTalent(player, "emot_wenyi") and not player.dead and player.faceup then -- 鹰嘴瘟医
        table.insert(cost_data, "emot_wenyi")
      end
    end
    if timesCheckFilter(cost_data, player) then
      event:setCostData(self, cost_data)
      return true
    end
  end,
  on_cost = Util.TrueFunc,
  on_use = function(self, event, target, player, data)
    local room = player.room
    if type(data) ~= "table" then return false end
    local cost_data = event:getCostData(self) or {}
    if table.contains(cost_data, "emot_wenyi") and player.faceup then -- 鹰嘴瘟医
      invokeTalent(player, "emot_wenyi", event)
      data.prevented = true
    end
    handleInvokedTalents(player, event)
  end,
})
